package io.kiki.sba.registry.server.metadata.metadataServer.impl;

import io.kiki.sba.registry.common.model.metaserver.cluster.VersionedList;
import io.kiki.sba.registry.common.model.metaserver.nodes.CentralControlNode;
import io.kiki.sba.registry.common.model.store.Url;
import io.kiki.sba.registry.exception.DisposeException;
import io.kiki.sba.registry.exception.InitializeException;
import io.kiki.sba.registry.lifecycle.impl.LifecycleHelper;
import io.kiki.sba.registry.server.metadata.bootstrap.config.NodeConfig;
import io.kiki.sba.registry.server.metadata.cluster.node.NodeAdded;
import io.kiki.sba.registry.server.metadata.cluster.node.NodeRemoved;
import io.kiki.sba.registry.server.metadata.lease.dataStoreNode.DataStoreNodeManager;
import io.kiki.sba.registry.server.metadata.lease.session.ClientInterfaceNodeManager;
import io.kiki.sba.registry.server.metadata.metadataServer.CurrentNodeClusterMetadataServer;
import io.kiki.sba.registry.server.metadata.slot.SlotManager;
import io.kiki.sba.registry.util.DatumVersionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;


@Component
public class DefaultCurrentNodeClusterMetadataServer extends LocalMetadataServer implements CurrentNodeClusterMetadataServer {

    @Autowired
    private NodeConfig nodeConfig;

    public DefaultCurrentNodeClusterMetadataServer() {
    }

    public DefaultCurrentNodeClusterMetadataServer(SlotManager slotManager, DataStoreNodeManager dataStoreNodeManager, ClientInterfaceNodeManager clientInterfaceNodeManager) {
        super(slotManager, dataStoreNodeManager, clientInterfaceNodeManager);
    }

    @PostConstruct
    public void postConstruct() throws Exception {
        LifecycleHelper.initializeIfPossible(this);
        LifecycleHelper.startIfPossible(this);
    }

    @PreDestroy
    public void preDestory() throws Exception {
        LifecycleHelper.stopIfPossible(this);
        LifecycleHelper.disposeIfPossible(this);
    }

    @Override
    protected void doInitialize() throws InitializeException {
        super.doInitialize();
        initMetaServers();
    }

    private void initMetaServers() {
        List<String> ipList = nodeConfig.getDataCenterToIpList().get(nodeConfig.getLocalDataCenter());
        List<CentralControlNode> list = new ArrayList<>();
        for (String ip : ipList) {
            list.add(new CentralControlNode(new Url(ip), nodeConfig.getLocalDataCenter()));
        }
        updateClusterMemberList(new VersionedList<>(list, DatumVersionUtil.nextId()));
    }

    @Override
    protected void doDispose() throws DisposeException {
        super.doDispose();
    }

    @Override
    public void renew(CentralControlNode centralControlNode) {
        super.renew(centralControlNode);
        notifyObservers(new NodeAdded<>(centralControlNode));
    }

    @Override
    public void cancel(CentralControlNode centralControlNode) {
        super.cancel(centralControlNode);
        notifyObservers(new NodeRemoved<>(centralControlNode));
    }


}
